package com.coolgor.coldot.service.auth.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.coolgor.coldot.common.PageCalculator;
import com.coolgor.coldot.dto.auth.FunctionExecution;
import com.coolgor.coldot.entity.auth.Function;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.coolgor.xutil.Common.DataTree;
import com.coolgor.xutil.Common.DataTreeNode;
import com.coolgor.coldot.dao.auth.FunctionDao;
import com.coolgor.coldot.dto.auth.FunctionExecution;
import com.coolgor.coldot.entity.auth.Function;
import com.coolgor.coldot.entity.auth.Role;
import com.coolgor.coldot.enums.auth.FunctionStateEnum;
import com.coolgor.coldot.exceptions.auth.FunctionOperationException;
import com.coolgor.coldot.service.auth.FunctionService;
import com.coolgor.coldot.common.PageCalculator;



@Service
public class FunctionServiceImpl implements FunctionService {
	private static Logger log = LoggerFactory.getLogger(FunctionServiceImpl.class);
	
	@Autowired
	private FunctionDao functionDao;
	
	@Override
	public Function getFunction(long functionID) {
		return functionDao.queryFunctionById(functionID);
	}

	@Override
	public FunctionExecution getFunctionList(Function functionCondition, int pageIndex, int pageSize) {
		//将页码转换成行码
		int rowIndex = PageCalculator.calculateRowIndex(pageIndex, pageSize);
		//依据查询条件，调用dao层返回相关的查询结果列表
		List<Function> functionList = functionDao.queryFunctionList(functionCondition, rowIndex, pageSize);
		//依据相同的查询条件，返回查询结果总数
		int count = functionDao.queryFunctionCount(functionCondition);
		FunctionExecution result = new FunctionExecution();
		if (functionList != null) {
			result.setState(FunctionStateEnum.SUCCESS.getState());
			result.setStateInfo(FunctionStateEnum.SUCCESS.getStateInfo());
			result.setFunctionList(functionList);
			result.setCount(count);
		} else {
			result.setState(FunctionStateEnum.INNER_ERROR.getState());
		}
		return result;
	}
	
	@Override
	public FunctionExecution getFunctionTree(Function functionCondition) {
		String status = null;
//		String status = Long.toString(functionCondition.getStatus());
		DataTree functionTree = new DataTree();
		DataTreeNode rootNode = new DataTreeNode();
		int level = 1;
		int numOfNode = 1;
		Function function = functionDao.queryFunctionById(functionCondition.getFunctionID());
		if (function != null) {
			rootNode.setNodeID(Long.toString(function.getFunctionID()));
			rootNode.setObject(function);
			rootNode.setLevel(level);
			rootNode.setRoot(true);
		} else {
			return new FunctionExecution(FunctionStateEnum.NULL);
		}
		List<Long> parentIDList = new ArrayList<Long>();
		parentIDList.add(function.getFunctionID());
		List<Function> functionList = functionDao.queryFunctionListByParentIDs(parentIDList, status);
		Map<Long,DataTreeNode> nodeMap1 = new HashMap<Long, DataTreeNode>();
		nodeMap1.put(function.getFunctionID(), rootNode);
		Map<Long,DataTreeNode> nodeMap2 ;
		DataTreeNode node ;
		while(functionList.size()>0) {
			level++;
			parentIDList = new ArrayList<Long>();
			nodeMap2 = new HashMap<Long, DataTreeNode>(); 
			for (int i=0; i<functionList.size(); i++) {
				numOfNode++;
				node = new DataTreeNode();
				node.setNodeID(Long.toString(functionList.get(i).getFunctionID()));
				node.setObject(functionList.get(i));
				node.setLevel(level);
				node.setRoot(false);
				nodeMap1.get(functionList.get(i).getParentID()).addChild(node);
				nodeMap2.put(functionList.get(i).getFunctionID(), node);
				parentIDList.add(functionList.get(i).getFunctionID());
			}
			nodeMap1 = nodeMap2;
			functionList = functionDao.queryFunctionListByParentIDs(parentIDList, status);
		}
		functionTree.setRoot(rootNode);
		functionTree.setNumOfNode(numOfNode);
		return new FunctionExecution(FunctionStateEnum.SUCCESS, functionTree);
	}
	
	
	@Override
	public FunctionExecution getFunctionTreeByRole(Function functionCondition, Role role) {
		if (null == role) {
			return new FunctionExecution(FunctionStateEnum.NULL);
		}
		String status = null;
//		String status = Long.toString(functionCondition.getStatus());
		DataTree functionTree = new DataTree();
		DataTreeNode rootNode = new DataTreeNode();
		int level = 1;
		int numOfNode = 1;
		Function function = functionDao.queryFunctionById(functionCondition.getFunctionID());
		if (function != null) {
			rootNode.setNodeID(Long.toString(function.getFunctionID()));
			rootNode.setObject(function);
			rootNode.setLevel(level);
			rootNode.setRoot(true);
		} else {
			return new FunctionExecution(FunctionStateEnum.NULL);
		}
		List<Long> parentIDList = new ArrayList<Long>();
		parentIDList.add(function.getFunctionID());
		List<Function> functionList = functionDao.queryFunctionListByParentIDsInRoleID(parentIDList, role.getRoleID(), status);
		Map<Long,DataTreeNode> nodeMap1 = new HashMap<Long, DataTreeNode>();
		nodeMap1.put(function.getFunctionID(), rootNode);
		Map<Long,DataTreeNode> nodeMap2 ;
		DataTreeNode node ;
		while(functionList.size()>0) {
			level++;
			parentIDList = new ArrayList<Long>();
			nodeMap2 = new HashMap<Long, DataTreeNode>(); 
			for (int i=0; i<functionList.size(); i++) {
				numOfNode++;
				node = new DataTreeNode();
				node.setNodeID(Long.toString(functionList.get(i).getFunctionID()));
				node.setObject(functionList.get(i));
				node.setLevel(level);
				node.setRoot(false);
				nodeMap1.get(functionList.get(i).getParentID()).addChild(node);
				nodeMap2.put(functionList.get(i).getFunctionID(), node);
				parentIDList.add(functionList.get(i).getFunctionID());
			}
			nodeMap1 = nodeMap2;
			functionList = functionDao.queryFunctionListByParentIDsInRoleID(parentIDList, role.getRoleID(), status);
		}
		functionTree.setRoot(rootNode);
		functionTree.setNumOfNode(numOfNode);
		return new FunctionExecution(FunctionStateEnum.SUCCESS, functionTree);
	}
	
	@Override
	@Transactional
	public FunctionExecution addFunction(Function function) throws FunctionOperationException {
		// 空值判断
		if (function == null) {
			return new FunctionExecution(FunctionStateEnum.NULL);
		}
		int effectedNum;
		try {
			// 添加
			effectedNum = functionDao.insert(function);
			if (effectedNum <= 0) {
				throw new FunctionOperationException("系统功能添加失败");
			} 
		} catch (Exception e) {
			throw new FunctionOperationException("addFunction error:" + e.getMessage());
		}
		return new FunctionExecution(FunctionStateEnum.SUCCESS, function);
	}

	@Override
	@Transactional
	public FunctionExecution modifyFunction(Function function) throws FunctionOperationException {
		// 空值判断
		if (function == null) {
			return new FunctionExecution(FunctionStateEnum.NULL);
		}
		int effectedNum;
		// 即将更新信息
		try {
			// 更新操作
			effectedNum = functionDao.update(function);
			if (effectedNum <= 0) {
				throw new FunctionOperationException("系统功能信息更新失败");
			} 
		} catch (Exception e) {
			throw new FunctionOperationException("Modify Function error:" + e.getMessage());
		}
		return new FunctionExecution(FunctionStateEnum.SUCCESS, function);
	}

	@Override
	@Transactional
	public FunctionExecution removeFunction(Function function) throws FunctionOperationException {
		// 空值判断
		if (function == null) {
			return new FunctionExecution(FunctionStateEnum.NULL);
		}
		int effectedNum;
		try {
			// 执行删除操作
			effectedNum = functionDao.delete(function);
			if (effectedNum <= 0) {
				throw new FunctionOperationException("系统功能删除失败");
			} 
		} catch (Exception e) {
			throw new FunctionOperationException("Delete Function error:" + e.getMessage());
		}
		return new FunctionExecution(FunctionStateEnum.SUCCESS, function);
	}

	@Override
	@Transactional
	public FunctionExecution batchRemoveFunction(List<Function> functionList) throws FunctionOperationException {
		// 空值判断
		if (functionList == null) {
			return new FunctionExecution(FunctionStateEnum.NULL);
		}
		List<Long> functionIDList = new ArrayList<Long>();
		for (int i=0; i<functionList.size(); i++) {
			functionIDList.add(functionList.get(i).getFunctionID());			
		}
		int effectedNum;
		try {
			// 执行删除操作
			effectedNum = functionDao.deleteBatch(functionIDList);
			if (effectedNum <= 0) {
				throw new FunctionOperationException("系统功能信息批量删除失败");
			} 
		} catch (Exception e) {
			throw new FunctionOperationException("Delete Function error:" + e.getMessage());
		}
		FunctionExecution exe = new FunctionExecution(FunctionStateEnum.SUCCESS);
		//将删除的记录总数加入到返回值
		exe.setCount(effectedNum);
		return exe;
	}



}
